package com.amqr.mediaplayer.widget;

import android.content.Context;
import android.media.AudioManager;
import android.media.MediaPlayer;
import android.net.Uri;
import android.support.annotation.NonNull;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.MotionEvent;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import android.view.View;
import android.view.ViewGroup;
import android.widget.FrameLayout;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.SeekBar;
import android.widget.TextView;
import android.widget.Toast;

import com.amqr.mediaplayer.R;
import com.amqr.mediaplayer.VideoUtils;


/**
 * User: LJM
 * Date&Time: 2017-06-28 & 16:02
 * Describe: Describe Text
 *
 * 关于时间显示：
 * 1、在缓冲完成（onPrepared）获取文件总时长
 * 2、开子线程，通过mediaPlayer.getCurrentPosition();更新播放进度
 *
 * 关于SeekBar进度条
 * 1、在缓冲完成（onPrepared）设置总长度为100
 * 2、开子线程，通过mediaPlayer.getCurrentPosition();计算百分比，最后更新进度
 *
 *
 */
public class AMQRVideoPlayerController extends FrameLayout implements View.OnTouchListener, View.OnClickListener {
    private static final String TAG = "AMQR_TAG";
    private Context mContext;

    private  SurfaceView surfaceView;
    private MediaPlayer mediaPlayer;

    // ==自身的控件
    private TextView mTvNowTime;
    private TextView mTvAllTime;
    private TextView mTvReplay;
    private LinearLayout mLlLoading;
    private LinearLayout mLlTop;
    private LinearLayout mLlBottomTime;
    private LinearLayout mLlCompleted;
    private ImageView mIvCenterStart;
    private ImageView mIvBgImage;
    private ImageView mTvBottomPauseOrRestart;
    private SeekBar mSbar;


    // 变量
    private boolean mIsFullAllScreen;  //是否居中铺满，要么保持原比例
    private boolean mIsAutoPlay;  //是否自动播放
    private boolean mIsLoop;  //是否循环播放
    private boolean mIsVideoSizeKnown;
    private int svFarentWidth;
    private int svFarentHeight;
    private boolean mIsVideoReadyToBePlayed;

    private boolean mIsPlayerCompletion;
    private Boolean mIsplaying;


    private int currentPosition;// 当前进度
    private int mAllDuration; // 音视频总长度


    private String sourcePath;  //有待改进，这样只有一种来源



    // 接口
    private IControllerOperate mIControllerOperate;

    public void setControllerOperate(IControllerOperate mIControllerOperate){
        this.mIControllerOperate = mIControllerOperate;
    }


    public AMQRVideoPlayerController(@NonNull Context context,SurfaceView surfaceView,String sourcePath) {
        super(context);
        this.mContext = context;
        this.surfaceView = surfaceView;
        this.sourcePath = sourcePath;
        init();
        this.setOnTouchListener(this); // 复写Touch，后期需要左侧上下滑动控制亮度，右侧上下滑动控制音量
    }

    private void init() {
        View inflate = LayoutInflater.from(mContext).inflate(R.layout.item_controller, this, true);
        mediaPlayer = new MediaPlayer();

        mIvCenterStart = (ImageView) inflate.findViewById(R.id.mIvCenterStart);
        mTvBottomPauseOrRestart = (ImageView) inflate.findViewById(R.id.mTvBottomPauseOrRestart);
        mIvBgImage = (ImageView) inflate.findViewById(R.id.mIvBgImage);
        mTvNowTime = (TextView) inflate.findViewById(R.id.mTvNowTime);
        mTvAllTime = (TextView) inflate.findViewById(R.id.mTvAllTime);

        mLlLoading = (LinearLayout) inflate.findViewById(R.id.mLlLoading);
        mLlBottomTime = (LinearLayout) inflate.findViewById(R.id.mLlBottomTime);
        mLlCompleted = (LinearLayout) inflate.findViewById(R.id.mLlCompleted);
        mTvReplay = (TextView) inflate.findViewById(R.id.mTvReplay);
        mLlTop = (LinearLayout) inflate.findViewById(R.id.mLlTop);
        mSbar = (SeekBar) inflate.findViewById(R.id.mSbar);

        mLlBottomTime.setVisibility(View.GONE);
        mLlTop.setVisibility(View.GONE);
        mIvCenterStart.setOnClickListener(this);
        mTvBottomPauseOrRestart.setOnClickListener(this);
        mTvReplay.setOnClickListener(this);

        setSurfaceListener();

    }

    private void setSurfaceListener() {
        // 设置Surface不维护自己的缓冲区，而是等待屏幕的渲染引擎将内容推送到用户面前
        surfaceView.getHolder().setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
        surfaceView.getHolder().addCallback(new SurfaceHolder.Callback() {
            @Override
            public void surfaceDestroyed(SurfaceHolder holder) {
                Log.d(TAG,"=== addCallback --- surfaceDestroyed");
                if (mediaPlayer != null && mediaPlayer.isPlaying()) {
                    currentPosition = mediaPlayer.getCurrentPosition();
                    mediaStop();


                    //mediaPlayer.pause();
                }
            }
            @Override
            public void surfaceCreated(SurfaceHolder holder) {
                Log.d(TAG,"=== addCallback --- surfaceCreated");
                if (currentPosition > 0 || mIsAutoPlay) {
                    try {
                        mediaPlay();// 开始播放
                        //mediaPlayer.seekTo(currentPosition);// 并直接从指定位置开始播放
                        //currentPosition = 0;
                    } catch (Exception e) {
                    }
                }

                mIvCenterStart.setVisibility(VISIBLE);
                mLlBottomTime.setVisibility(GONE);

            }

            @Override
            public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
                Log.d(TAG,"=== addCallback --- surfaceChanged");
            }
        });




        // 按照谷歌的说法 when the video size is known or updated. 大小已知或者改变时被调用
        mediaPlayer.setOnVideoSizeChangedListener(new MediaPlayer.OnVideoSizeChangedListener() {
            @Override
            public void onVideoSizeChanged(MediaPlayer mediaPlayer, int videoWidth, int videoHeight) {
                Log.d(TAG,"=== onVideoSizeChanged");

                ViewGroup parent = (ViewGroup) surfaceView.getParent();
                svFarentWidth = parent.getWidth();
                svFarentHeight = parent.getHeight();
                if (videoWidth == 0 || videoHeight == 0) {
                    return;
                }

                mIsVideoSizeKnown = true;
                final FrameLayout.LayoutParams params = (FrameLayout.LayoutParams) surfaceView.getLayoutParams();
                if(mIsFullAllScreen){ // 铺满
                    float scaleVideo= videoWidth /(float)videoHeight;
                    float scaleSurface= svFarentWidth /(float)svFarentHeight;
                    if(scaleVideo<scaleSurface){
                        params.width=svFarentWidth;
                        params.height= (int) (svFarentWidth/scaleVideo);
                        params.setMargins(0,(svFarentHeight-params.height)/2,0,(svFarentHeight-params.height)/2);
                    }else{
                        params.height=svFarentHeight;
                        params.width= (int) (svFarentHeight*scaleVideo);
                        params.setMargins((svFarentWidth-params.width)/2,0,(svFarentWidth-params.width)/2,0);
                    }
                }else{ //保持原比例
                    if (videoWidth > svFarentWidth || videoHeight > svFarentHeight) {
                        float scaleVideo = videoWidth / (float) videoHeight;
                        float scaleSurface = svFarentWidth / svFarentHeight;
                        if (scaleVideo > scaleSurface) {
                            params.width = svFarentWidth;
                            params.height = (int) (svFarentWidth / scaleVideo);
                            params.setMargins(0, (svFarentHeight - params.height) / 2, 0, (svFarentHeight - params.height) / 2);
                        } else {
                            params.height = videoHeight;
                            params.width = (int) (svFarentHeight * scaleVideo);
                            params.setMargins((svFarentWidth - params.width) / 2, 0, (svFarentWidth - params.width) / 2, 0);
                        }
                    }
                }
                surfaceView.setLayoutParams(params);
                if (mIsVideoReadyToBePlayed && mIsVideoSizeKnown) {
                    mediaPlayer.start();
                }
            }
        });

        mediaPlayer.setOnErrorListener(new MediaPlayer.OnErrorListener() {
            @Override
            public boolean onError(MediaPlayer mediaPlayer,  int what, int extra) {
                Log.d(TAG,"=== onError   "+what +"   extra:"+extra);
                return false;
            }
        });

        // 播放完成
        mediaPlayer.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {
            @Override
            public void onCompletion(MediaPlayer mediaPlayer) {
                Log.d(TAG,"=== onCompletion ：" + mediaPlayer);

                // 重新播放的时候会异常触发一次，所以这里这行控制一下，之后是正常播放到结束，才认为是Completion
                if(mIsVideoReadyToBePlayed){
                    mLlCompleted.setVisibility(VISIBLE);
                    mLlBottomTime.setVisibility(GONE);

                    mSbar.setProgress(0);
                    mTvNowTime.setText(VideoUtils.formatTime(0));
                    mIsPlayerCompletion = true;
                }


            }
        });


        // 以上是mediaPlayer的监听

        mSbar.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
            @Override
            public void onProgressChanged(SeekBar seekBar, int i, boolean b) {
            }

            @Override
            public void onStartTrackingTouch(SeekBar seekBar) {
                Log.d(TAG,"=== onStartTrackingTouch  开始");
            }

            @Override
            public void onStopTrackingTouch(SeekBar seekBar) {
                Log.d(TAG,"=== onStopTrackingTouch    Stop ");

                int process = seekBar.getProgress();
                if(mediaPlayer != null && mediaPlayer.isPlaying()) {
                    mediaPlayer.seekTo(process);
                }
            }
        });

    }

    private void startUpdateProgressThread(final MediaPlayer mediaPlayer) {
        new Thread() {
            public void run() {
                mIsplaying = true;
                while (mIsplaying) {
                    AMQRVideoPlayerController.this.post(new Runnable() {
                        @Override
                        public void run() {
                           updateProgress();
                        }
                    });

                    try {
                        Thread.sleep(500);
                    } catch (InterruptedException e) {
                        // TODO Auto-generated catch block
                        e.printStackTrace();
                    }
                }

            };

        }.start();
    }

    private void updateProgress() {
        final int position = mediaPlayer.getCurrentPosition();
        //Log.d(TAG,"current position："+position);
        //int progress = (int) (100f * position / mAllDuration);
        mSbar.setProgress(position);
        mTvNowTime.setText(VideoUtils.formatTime(position));
    }


    @Override
    public boolean onTouch(View view, MotionEvent motionEvent) {
        return false;
    }

    @Override
    public void onClick(View view) {
        switch (view.getId()){
            case R.id.mIvCenterStart:
                mIControllerOperate.centerStart();
                break;

            case R.id.mTvBottomPauseOrRestart:
                mIControllerOperate.pauseOrRestart();
                break;
            case R.id.mTvReplay:
                mLlCompleted.setVisibility(GONE);
                mIControllerOperate.rePlay();

                break;



        }
    }

    public interface  IControllerOperate{
        void centerStart();
        void pauseOrRestart();
        void rePlay();
    }


    // ====  getter  start

    public TextView getTvNowTime() {
        return mTvNowTime;
    }

    public TextView getTvAllTime() {
        return mTvAllTime;
    }

    public LinearLayout getLlLoading() {
        return mLlLoading;
    }

    public LinearLayout getLlBottomTime() {
        return mLlBottomTime;
    }

    public ImageView getIvCenterStart() {
        return mIvCenterStart;
    }

    public ImageView getTvBottomPauseOrRestart() {
        return mTvBottomPauseOrRestart;
    }

    // ====  getter  end


    public void mediaPauseOrRestart(){
        if (mediaPlayer.isPlaying()) {
            mediaPlayer.pause();
            mTvBottomPauseOrRestart.setBackgroundResource(R.drawable.ic_player_pause);
            Log.d(TAG,"=== mediaPauseOrRestart  ==== pause");
        } else {
            mediaPlayer.start();
            mTvBottomPauseOrRestart.setBackgroundResource(R.drawable.ic_player_start);
            Log.d(TAG,"=== mediaPauseOrRestart  ==== start");
        }
    }


    /**
     * 初始化播放，当且仅当 初始化播放资源 和MediaPlayer会调用
     * android.media.MediaPlayer.OnPreparedListener#onPrepared(android.media.MediaPlayer)
     */
    public void mediaPlay(){

        Log.d(TAG,"=== mediaPlay");
        try {
            mLlLoading.setVisibility(View.VISIBLE);
            mIvCenterStart.setVisibility(GONE);

            mediaPlayer.reset();
            // setAudioStreamType 在8.0 已经不推荐使用了，但是实测8.0还是可以正常运行的，官方推荐使用 setAudioAttributes(AudioAttributes) 替代
            mediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC); //指定流媒体的类型 MediaPlayer设置StreamType需要prepare() or prepareAsync()之前

            Uri uri = Uri.parse(sourcePath);
            mediaPlayer.setDataSource(mContext, uri);// 设置需要播放的视频
            mediaPlayer.prepareAsync(); // 官方推荐的异步方式进行，异步方式需要在setOnPreparedListener的回到里面手动调用一次 mediaPlayer.start();
            mediaPlayer.setDisplay(surfaceView.getHolder());  // 把视频画面输出到SurfaceView
            //mediaPlayer.start(); // 播放   当使用 prepareAsync 异步加载资源的方式时，这里的 start()不需要调。 （同步的方式就需要）


            // 缓冲监听
            mediaPlayer.setOnPreparedListener(new MediaPlayer.OnPreparedListener() {
                @Override
                public void onPrepared(final MediaPlayer mediaPlayer) {
                    Log.d(TAG,"=== onPrepared");

                    mLlLoading.setVisibility(View.GONE);
                    mIsVideoReadyToBePlayed = true;
                    mIsPlayerCompletion = false;
                    if (mIsVideoReadyToBePlayed && mIsVideoSizeKnown) {
                        mIvCenterStart.setVisibility(View.GONE);
                        mIvBgImage.setVisibility(View.GONE);
                        mLlCompleted.setVisibility(View.GONE);
                        mLlBottomTime.setVisibility(View.VISIBLE);

                        // 总时长
                        mAllDuration = mediaPlayer.getDuration();
                        mTvAllTime.setText(VideoUtils.formatTime(mAllDuration));
                        mSbar.setMax(mAllDuration);

                        // 是否循环播放
                        if(mIsLoop){
                            mediaPlayer.setLooping(true); // 循环播放  mediaPlayer.setLooping(true);需要写在onPrepared才能生效
                        }

                        Toast.makeText(mContext, "开始播放！", Toast.LENGTH_LONG).show();
                        mediaPlayer.start();

                        startUpdateProgressThread(mediaPlayer);
                    }
                }
            });

        } catch (Exception e) {
        }

    }

    /**
     * 停止播放
     */
    public void mediaStop() {
        Log.d(TAG,"=== mediaStop");
        if (mediaPlayer != null && mediaPlayer.isPlaying()) {
            mediaPlayer.stop();
            mediaPlayer.release(); // 记得释放资源
            mediaPlayer = null;
            mIsplaying = false;
            //bt_play.setEnabled(true);
        }
    }


    public void rePlayer(){
        /*if(mediaPlayer!=null || mIsPlayerCompletion){
            mediaPlayer.seekTo(0);
            mediaPlayer.start();


            mLlBottomTime.setVisibility(VISIBLE);
        }else{
            mediaPlay();
        }*/
        mIsVideoReadyToBePlayed = false;
        mediaPlay();
    }


    /**
     * 是否铺满（不是完全全屏）
     * 是则铺满，否则保持原比例
     * @param fullAllScreen
     */
    public void setFullAllScreen(boolean fullAllScreen) {
        mIsFullAllScreen = fullAllScreen;
    }

    /**
     * 是否自动播放
     */
    public void setAutoPlay(boolean autoPlay) {
        mIsAutoPlay = autoPlay;
    }

    /**
     * 是否循环播放
     */
    public void setLoop(boolean loop) {
        mIsLoop = loop;
    }




}
